/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Server.SQL;

import Server.Helper.Analyzer;
import Server.Helper.StringHelper;
import java.sql.Types;
import java.util.Vector;
import Server.MyDataType.Attribute_Value;
import Server.MyDataType.MyDataDynamic;
import Server.lastproject.XMLManage;

/**
 *
 * @author CANG
 */
public class MyCommand 
{
    protected static String _sCommand;
    protected XMLManage _xmlManage;
    Vector<String> lstColumnsWhere = new Vector<>();
    Vector<String> lstExpression = new Vector<>();
    String table;
    
    public MyCommand(String command)
    {
        _sCommand = command;
        _xmlManage = new XMLManage();                
    }
    
    //lấy đoạn chuỗi đầu tiên trong chuỗi str cho đến khi gặp chuỗi delimiter và cắt _sCommand
    /*
     *  splitFirstString("Nguyen_Duc_Cang in Table_A ", " ")
     * -->
     *   _sCommand = "in Table_A" 
     */    
    public static String splitFirstString(String str, String delimiter)
    {
        String result = "";
        
        int index_split = -1;
        int len = str.length();
        for(int i = 0; i < len; i++)
        {
            if(str.charAt(i) == ' ')
            {
                index_split++;
                break;
            }
            index_split++;
        }
        
        if(index_split == -1 || index_split == len - 1)
        {
            return null;
        }
        
        result = str.substring(0, index_split);       
        _sCommand = str.substring(index_split + 1, len);
                
        return result;
    }
    
    //lấy chuỗi trước dấu chấm phẩy
    /*
     * splitGetComponentBefore_Parenthesis(tala , he he)
     
     * ---> tala 
     */
    public String splitGetComponentBefore_Parenthesis(String command)
    {
        String result = "";
        
        int index_split = -1;
        int len = command.length();
        for(int i = 0; i < len; i++)
        {
            if(command.charAt(i) == ' ' || command.charAt(i) == '(')
            {
                index_split++;
                break;
            }
            
            index_split++;            
        }    
        
        if(index_split == -1 || index_split == len - 1)
        {
            return null;
        }
        
        result = command.substring(0, index_split);
        if(_sCommand.charAt(index_split + 1) == ' ')
        {
            index_split += 1;
        }
        
        _sCommand = command.substring(index_split, len);
        
        return result;
        
    }
    
    //tim vị trí index của dấu ( và dấu )
    /*
     * getIndexCouple_Parenthesis("ta la (ai )i nay")
     * --> int[] a = {6, 10};     
     */
    public int[] getIndexCouple_Parenthesis(String command)
    {
        int[] lstIndex = {-1, -1};
        
        int index = 0;
        int len = command.length();
        for(int i = 0; i < len; i++)
        {
            if(command.charAt(i) == '(' && index == 0)
            {
                
                lstIndex[index] = i;
                index++;
            }

            if(command.charAt(i) == ')' && index == 1)
            {
                lstIndex[index] = i;
                break;
            }
        }
        return lstIndex;
        
    }
    
    public int[] getIndexCouple_Quote(String command)
    {
        int[] lstIndex = {-1, -1};
        
        int index = 0;
        int len = command.length();
        for(int i = 0; i < len; i++)
        {
            if(command.charAt(i) == '\'')
            {
                lstIndex[index++] = i;
                if(index == 2)
                    break;
            }
        }
        return lstIndex;
    }
    
    //tạo ra 2 kiểu dữ liệu là Attribute_Value và MyDataDynamic để phục vụ cho dữ liệu không theo cấu trúc nhất định
     //khi thực hiện câu truy vấn select
    public Vector<Attribute_Value> createListAttribute(String[] lstNameColumns, String[] lstValues)
    {
        Vector<Attribute_Value> vtValues = new Vector<Attribute_Value>(0);
        for(int i = 0; i < lstNameColumns.length; i++)
        {
            Attribute_Value attribute_Value = new Attribute_Value();
            attribute_Value.NameAttribute = lstNameColumns[i];
            attribute_Value.Value = lstValues[i];
            
            vtValues.add(attribute_Value);
        }
        return vtValues;
    }
    
    public Vector<String> SplitClauseWhere(String where)
    {
        where = ParseNotIn2And(where);
        where = ParseIn2Or(where);
        Vector<String> lstCon = new Vector<>();
        
        String[] lstFirt = where.split(" ");
        Vector<Integer> lstIndex = new Vector<>();
        lstIndex.add(-1);
        for(int i = 0; i<lstFirt.length; i++)
        {
            if(lstFirt[i].equals("AND") || lstFirt[i].equals("OR"))
            {
                lstIndex.add(i);
            }
        }
        
        for(int i = 1; i< lstIndex.size(); i++)
        {
            String str = "";
            for(int j = lstIndex.get(i-1) + 1; j<lstIndex.get(i); j++)
            {
                str += lstFirt[j] + " ";
            }
            lstCon.add(str.trim());
            lstCon.add(lstFirt[lstIndex.get(i)]);
        }
        String str = "";
        for(int i = lstIndex.get(lstIndex.size()-1) + 1; i<lstFirt.length; i++)
        {
            str += lstFirt[i] + " ";
        }
        lstCon.add(str.trim());
        
        return lstCon;
    }

    public Vector<MyDataDynamic> ExcuteWhere()
    {
        Vector<MyDataDynamic> lstData = new Vector<>();
        XMLManage xml = new XMLManage();
        
        if(this.lstColumnsWhere.size() > 0)
        {
            for(int i = 0; i<lstColumnsWhere.size(); i++)
            {
                if(lstColumnsWhere.get(i).equals("AND") || lstColumnsWhere.get(i).equals("OR"))
                {
                    lstExpression.add(lstColumnsWhere.get(i));
                    continue;
                }
                MyDataDynamic data = xml.getDataDynamicWithSingleCondition(table, lstColumnsWhere.get(i));
                lstData.add(data);
            }
            
            while(lstExpression.size() > 0)
            {
                MyDataDynamic temp = new MyDataDynamic();
                temp = xml.mergeDataDynamicAndOr(lstData.get(0), lstData.get(1), lstExpression.get(0));
                lstData.elementAt(0)._vtNameColumn = temp._vtNameColumn;
                lstData.elementAt(0)._vtRowData = temp._vtRowData;
                lstData.remove(1);
                lstExpression.remove(0);
            }
        }
        
        return lstData;
    }
    
    public String ParseIn2Or(String where)
    {
        try
        {
            // Trích ra mệnh đề IN
            String[] lstFirt1 = where.split(" ");
            Vector<String> lstFirt = new Vector<>();
            for(int i = 0; i<lstFirt1.length; i++)
                lstFirt.add(lstFirt1[i]);

            // Lưu giữ String
            Vector<String> lstIN = new Vector<>();

            // Tìm ra các vị trí của IN
            Vector<Integer> lstIndex = new Vector<>(); 
            for(int i = 0; i<lstFirt.size(); i++)
            {
                if(lstFirt.get(i).toUpperCase().compareTo("IN") == 0)
                {
                    lstIndex.add(i);
                }
            }

            // Lưu vị trí đã lấy
            Vector<Vector<Integer>> lstIndexRe = new Vector<>();

            // Lấy ra chuỗi IN
            for(int i = 0; i<lstIndex.size(); i++)
            {
                Vector<Integer> lstRe = new Vector<>();
                String in = "";
                in = lstFirt.get(lstIndex.get(i) - 1) + " IN ";
                // Xóa
                lstRe.add(lstIndex.get(i) - 1);
                lstRe.add(lstIndex.get(i));
                for(int j = lstIndex.get(i) + 1; j<lstFirt.size(); j++)
                {
                    if(lstFirt.get(j).compareTo(")") == 0)
                    {
                        in += " )";
                        lstRe.add(j);
                        break;
                    }
                    in += lstFirt.get(j) + " ";
                    lstRe.add(j);
                }
                lstIN.add(in.trim());
                lstIndexRe.add(lstRe);
            }

            StringHelper help = new StringHelper();
            // Thực hiện chuyển đổi
            for(int i = 0; i<lstIN.size(); i++)
            {
                String adsfkj = help.ParseIN2OR(lstIN.get(i));
                lstIN.set(i, adsfkj);
            }
            // Thực hiện thay thế chuỗi.
            for(int i = 0; i<lstIndexRe.size(); i++)
            {
                lstFirt.set(lstIndexRe.get(i).get(0), lstIN.get(i));
            }
            for(int i = 0; i<lstIndexRe.size(); i++)
            {
                for(int j = lstIndexRe.get(i).size() - 1; j > 0; j--)
                {
                    int index = lstIndexRe.get(i).get(j);
                    lstFirt.remove(index);
                }
            }

            // Nối lại thành chuỗi Where
            where = "";
            for(int i = 0; i<lstFirt.size(); i++)
            {
                where += lstFirt.get(i) + " ";
            }
            where = where.trim();
        }
        catch(Exception e)
        {}
        return where;
    }
    
    public String ParseNotIn2And(String where)
    {
        try
        {
            // Trích ra mệnh đề NOT IN
            String[] lstFirt1 = where.split(" ");
            Vector<String> lstFirt = new Vector<>();
            for(int i = 0; i<lstFirt1.length; i++)
                lstFirt.add(lstFirt1[i]);
            // Xóa NOT
            for(int i = lstFirt.size() - 1; i >= 0; i++)
            {
                if(lstFirt.get(i).compareTo("NOT") == 0)
                    lstFirt.remove(i);
            }
            // Lưu giữ String
            Vector<String> lstIN = new Vector<>();

            // Tìm ra các vị trí của IN
            Vector<Integer> lstIndex = new Vector<>(); 
            for(int i = 0; i<lstFirt.size(); i++)
            {
                if(lstFirt.get(i).toUpperCase().compareTo("IN") == 0)
                {
                    lstIndex.add(i);
                }
            }

            // Lưu vị trí đã lấy
            Vector<Vector<Integer>> lstIndexRe = new Vector<>();

            // Lấy ra chuỗi IN
            for(int i = 0; i<lstIndex.size(); i++)
            {
                Vector<Integer> lstRe = new Vector<>();
                String in = "";
                in = lstFirt.get(lstIndex.get(i) - 1) + " NOT IN ";
                // Xóa
                lstRe.add(lstIndex.get(i) - 1);
                lstRe.add(lstIndex.get(i));
                for(int j = lstIndex.get(i) + 1; j<lstFirt.size(); j++)
                {
                    if(lstFirt.get(j).compareTo(")") == 0)
                    {
                        in += " )";
                        lstRe.add(j);
                        break;
                    }
                    in += lstFirt.get(j) + " ";
                    lstRe.add(j);
                }
                lstIN.add(in.trim());
                lstIndexRe.add(lstRe);
            }

            StringHelper help = new StringHelper();
            // Thực hiện chuyển đổi
            for(int i = 0; i<lstIN.size(); i++)
            {
                String adsfkj = help.ParseNOTIN2AND(lstIN.get(i));
                lstIN.set(i, adsfkj);
            }
            // Thực hiện thay thế chuỗi.
            for(int i = 0; i<lstIndexRe.size(); i++)
            {
                lstFirt.set(lstIndexRe.get(i).get(0), lstIN.get(i));
            }
            for(int i = 0; i<lstIndexRe.size(); i++)
            {
                for(int j = lstIndexRe.get(i).size() - 1; j > 0; j--)
                {
                    int index = lstIndexRe.get(i).get(j);
                    lstFirt.remove(index);
                }
            }

            // Nối lại thành chuỗi Where
            where = "";
            for(int i = 0; i<lstFirt.size(); i++)
            {
                where += lstFirt.get(i) + " ";
            }
            where = where.trim();
        }
        catch(Exception e){}
        
        return where;
    }
}
